<template>
  <el-row class="search-form">
    <el-form ref="form" :inline="true" :label-width="`${labelWidth}px`">
      <el-col v-for="(item, index) of items" :key="index" :span="item.span || 6">
        <el-form-item :label="item.showLabel && item.name">
          <el-input
            v-if="!item.type || item.type === 'input'"
            v-model="searchParams[item.key]"
            size="small"
            :disabled="item.disabled"
            v-bind="setAttrs(item)"
            :maxlength="item.maxLen || 500"
            :placeholder="item.placeholder || `请输入${item.name}`"
          />
          <el-input
            v-else-if="item.type === 'number'"
            v-model="searchParams[item.key]"
            type="number"
            size="small"
            :disabled="item.disabled"
            v-bind="setAttrs(item)"
            :placeholder="item.placeholder || `请输入${item.name}`"
            @input="if(item.maxLen && searchParams[item.key].length>item.maxLen) searchParams[item.key]=searchParams[item.key].slice(0,item.maxLen)"
          />
          <el-input
            v-else-if="item.type === '_number'"
            ref="_number"
            v-model="searchParams[item.key]"
            type="input"
            size="small"
            :maxlength="item.maxLen || 500"
            :disabled="item.disabled"
            v-bind="setAttrs(item)"
            :placeholder="item.placeholder || `请输入${item.name}`"
            @input="searchParams[item.key] = searchParams[item.key].replace(/[^\d]/g,'')"
          />
          <el-input
            v-else-if="item.type === 'watchCascader'"
            v-model="searchParams[item.key]"
            size="small"
            v-bind="setAttrs(item)"
            :placeholder="item.placeholder || `请输入${item.name}`"
            @input="searchCascderOptions(item)"
          />
          <el-select
            v-else-if="item.type === 'select'"
            v-model="searchParams[item.key]"
            v-bind="setAttrs(item)"
            allow-clear
            size="small"
            :placeholder="item.placeholder || `请选择${item.name}`"
          >
            <el-option
              v-for="(option, i) of (item.options || selectOptions)"
              :key="i"
              :value="option[item['props']&&item['props']['value'] || 'value']"
              :label="option[item['props']&&item['props']['label'] || 'label']"
            />
          </el-select>
          <el-select
            v-else-if="item.type === 'remote'"
            v-model="searchParams[item.bindKey]"
            :multiple="item.multiple"
            filterable
            remote
            reserve-keyword
            v-bind="setAttrs(item)"
            :placeholder="item.placeholder || `请输入${item.name}`"
            :remote-method="(query)=>{ remoteMethod(query,item) }"
            :loading="remoteLoading"
          >
            <el-option
              v-for="(v, idx) in remoteOptions"
              :key="idx"
              :label="v[item['props']&&item['props']['label'] || item.label]"
              :value="v[item['props']&&item['props']['value'] || item.value]"
            />
          </el-select>
          <el-cascader
            v-else-if="item.type === 'cascader'"
            v-model="searchParams[item.key]"
            :placeholder="item.placeholder || `请选择${item.name}`"
            v-bind="setAttrs(item)"
            size="small"
            :options="cascderOptions"
          />
          <el-cascader
            v-else-if="item.type === 'cascaderThree'"
            v-model="searchParams[item.key]"
            :placeholder="item.placeholder || `请选择${item.name}`"
            v-bind="setAttrs(item)"
            size="small"
            :options="cascaderThreeOptions"
          />
          <el-date-picker
            v-else-if="item.type === 'date'"
            v-model="searchParams[item.key]"
            type="date"
            placeholder="选择日期"
            v-bind="setAttrs(item)">
          </el-date-picker>
          <el-date-picker
            v-else-if="item.type === 'date-picker'"
            v-model="searchParams[item.key]"
            :default-time="['00:00:00', '23:59:59']"
            prefix-icon=""
            :placeholder="item.placeholder || `请选择${item.name}`"
            v-bind="setAttrs(item)"
            size="small"
            type="daterange"
            range-separator="-"
            :start-placeholder="item.startPlaceholder || '开始日期'"
            :end-placeholder="item.endPlaceholder || '结束日期'"
          />
          <el-date-picker
            v-else-if="item.type === 'datetimerange'"
            v-model="searchParams[item.key]"
            type="datetimerange"
            v-bind="setAttrs(item)"
            range-separator="-"
            :start-placeholder="item.startPlaceholder || '开始日期'"
            :end-placeholder="item.endPlaceholder || '结束日期'"
          />
          <template v-else-if="item.type === 'input-range'">
            <el-row :gutter="10">
              <el-col :span="11">
                <el-input
                  v-model="searchParams[item.key1]"
                  size="small"
                  :disabled="item.disabled"
                  v-bind="setAttrs(item)"
                  :placeholder="item.placeholder1 || item.placeholder || `请输入`"
                />
              </el-col>
              <el-col :span="2" style="text-align:center">
                <span>{{ item.rangeSeparator }}</span>
              </el-col>
              <el-col :span="11">
                <el-input
                  v-model="searchParams[item.key2]"
                  size="small"
                  :disabled="item.disabled"
                  v-bind="setAttrs(item)"
                  :placeholder="item.placeholder2 || item.placeholder || `请输入`"
                />
              </el-col>
            </el-row>
          </template>
          <template v-else-if="item.type === 'dateTime'">
            <el-date-picker
              v-model="searchParams[item.key]"
              type="datetime"
              :placeholder="item.placeholder || `请选择${item.name}`"
              default-time="00:00:00"
              v-bind="setAttrs(item)"
              />
          </template>
          <template v-else-if="item.type === 'date-time'">
            <el-row :gutter="10">
              <el-col :span="12">
                <el-date-picker
                  v-model="searchParams[item.key1]"
                  :placeholder="item.placeholder1 || `请选择${item.name}`"
                  v-bind="setAttrs(item)"
                  size="small"
                  type="date"
                  range-separator="-"
                />
              </el-col>
              <el-col :span="12">
                <el-time-picker
                  v-model="searchParams[item.key2]"
                  :placeholder="item.placeholder2 || `请选择${item.name}`"
                  v-bind="setAttrs(item)"
                  size="small"
                  type="date"
                  range-separator="-"
                />
              </el-col>
            </el-row>
          </template>
          <template v-else-if="item.type === 'date-rangeTime'">
            <el-row :gutter="10">
              <el-col :span="10">
                <el-date-picker
                  v-model="searchParams[item.key1]"
                  :placeholder="item.placeholder || `请选择${item.name}`"
                  v-bind="setAttrs(item)"
                  size="small"
                  type="date"
                  value-format="yyyy-MM-dd"
                />
              </el-col>
              <el-col :span="14">
                <el-time-picker
                  v-model="searchParams[item.key2]"
                  value-format="HH:mm:ss"
                  size="small"
                  is-range
                  range-separator="至"
                  start-placeholder="开始时间"
                  end-placeholder="结束时间"
                  placeholder="选择时间范围"
                />
              </el-col>
            </el-row>
          </template>
          <template v-else-if="item.type === 'section'">
            <el-input
              v-model="searchParams[item.minKey]"
              class="section-input"
              v-bind="setAttrs(item)"
              size="small"
              :placeholder="item.placeholder || `请输入${item.name}`"
            /><span class="symbol">-</span>
            <el-input
              v-model="searchParams[item.maxKey]"
              class="section-input"
              size="small"
              v-bind="setAttrs(item)"
              :placeholder="item.placeholder || `请输入${item.name}`"
            />
          </template>
          <template v-else-if="item.type === 'selectGroup3'">
            <el-row :gutter="10">
              <el-col :span="8">
                <el-select
                  v-model="searchParams[item.key1]"
                  :placeholder="`请选择${item.placeholder1}`"
                  @change="selectGroupChange1"
                >
                  <el-option
                    v-for="(option, idx) in selectGroupOptions1"
                    :key="idx"
                    :label="option[item.label]"
                    :value="option[item.value]"
                  />
                </el-select>
              </el-col>
              <el-col :span="8">
                <el-select
                  v-model="searchParams[item.key2]"
                  :placeholder="`请选择${item.placeholder2}`"
                  @change="selectGroupChange2"
                >
                  <el-option
                    v-for="(option, idx) in selectGroupOptions2"
                    :key="idx"
                    :label="option[item.label]"
                    :value="option[item.value]"
                  />
                </el-select>
              </el-col>
              <el-col :span="8">
                <el-select
                  v-model="searchParams[item.key3]"
                  :placeholder="`请选择${item.placeholder3}`"
                >
                  <el-option
                    v-for="(option, idx) in selectGroupOptions3"
                    :key="idx"
                    :label="option[item.label]"
                    :value="option[item.value]"
                  />
                </el-select>
              </el-col>
            </el-row>
          </template>
          <template v-else-if="item.type === 'selectAddress'">
            <el-row :gutter="10">
              <el-col :span="item.key3 ? 8 : 12">
                <el-select v-model="searchParams[item.key1]" :placeholder="`请选择${item.placeholder1||''}`" @change="e => selectAddressChange1(e, item)">
                  <el-option
                    v-for="(option, idx) in selectAddressOptions1"
                    :key="idx"
                    :label="option[item.props1.label]"
                    :value="option[item.props1.value]"
                  />
                </el-select>
              </el-col>
              <el-col v-if="item.key2" :span="item.key3 ? 8 : 12">
                <el-select v-model="searchParams[item.key2]" :placeholder="`请选择${item.placeholder2||''}`" @change="selectAddressChange2">
                  <el-option
                    v-for="(option, idx) in selectAddressOptions2"
                    :key="idx"
                    :label="option[item.props2.label]"
                    :value="option[item.props2.value]"
                  />
                </el-select>
              </el-col>
              <el-col v-if="item.key3" :span="8">
                <el-select v-model="searchParams[item.key3]" :placeholder="`请选择${item.placeholder3||''}`" @change="selectAddressChange3">
                  <el-option
                    v-for="(option, idx) in selectAddressOptions3"
                    :key="idx"
                    :label="option[item.props3.label]"
                    :value="option[item.props3.value]"
                  />
                </el-select>
              </el-col>
            </el-row>
          </template>
          <template v-else-if="item.type === 'selectAddress2'">
            <el-row :gutter="10">
              <el-col :span="12">
                <el-select
                  v-model="searchParams[item.key1][0]"
                  :placeholder="`请选择${item.placeholder1}`"
                  @change="e => addressChange1(e, item)"
                >
                  <el-option
                    v-for="(option, idx) in addressOptions1"
                    :key="idx"
                    :label="option[item.props1.label]"
                    :value="option[item.props1.value]"
                  />
                </el-select>
              </el-col>
              <el-col :span="12">
                <el-select
                  v-model="searchParams[item.key2][0]"
                  :placeholder="`请选择${item.placeholder2}`"
                  @change="addressChange2"
                >
                  <el-option
                    v-for="(option, idx) in addressOptions2"
                    :key="idx"
                    :label="option[item.props2.label]"
                    :value="option[item.props2.value]"
                  />
                </el-select>
              </el-col>
            </el-row>
          </template>
        </el-form-item>
      </el-col>
      <div class="button-group">
        <el-form-item class="button" :label="isShowBtnLabel? ' ' : null">
          <!-- button 前置插槽 -->
          <slot name="prefix-button" />
          <el-button type="primary" icon="el-icon-search" @click="handleSearch">查 询</el-button>
          <el-button icon="el-icon-refresh" @click="handleReset">重 置</el-button>
          <!-- button 后置插槽 -->
          <slot name="suffix-button" />
        </el-form-item>
      </div>
    </el-form>
    <div class="extra-button-container">
      <slot name="extra-button" />
      <div class="extra-button-right">
        <slot name="extra-button-right" />
      </div>
    </div>

  </el-row>
</template>
<script>
/**
 * dom结构基于element-ui 依赖于 element-ui 的 row form input select cascader date-picker button等组件
 * cloneDeep方法依赖于lodash库
 * items 为过滤条件，可以在对应的项中自定义下拉选项的名称（optionNamekey）和值（optionValuekey）的键，默认分别取 name 和 id
 * items 如何要下拉框显示 placeholder，对应的下拉框的初始值可以设置为 undefined 或者 不定义查询参数，如果设置为空， placeholder 不会显示。
 * searchParams 为接口查询参数对象
 *
 * items 示例：
 * [{ name: '发起人1', value: 123, key: 'name1', placeholder: 'xxxxx' },{name: '输入框',value: '选项1',key: 'repairerId',type: 'select',options: [{value: '选项1', label: '黄金糕'},{value: '选项2',label: '双皮奶'}]},{ name: '时间', key: 'roomId', type: 'date-picker', options: [] }]
 */
import request from '@/utils/request'
import { filterCascaderData } from '@/utils'
import { getProvince, getCity, getDistrict, getRolesAddress, getByAmapCode } from '@/api/common'
export default {
  name: 'TableFilter',
  props: {
    // 表单参数
    searchParams: {
      type: Object,
      default: () => {
        return {}
      }
    },
    // 表单配置
    items: {
      type: Array,
      default: () => {
        return []
      }
    },
    labelWidth: {
      type: Number,
      default: 100
    },
    isShowBtnLabel: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      // 保存初始化时的项
      initSearchParams: {},
      remoteLoading: false, // 联想搜索框loading
      remoteOptions: [], // 联想搜索的结果
      cascderOptions: [],
      cascaderThreeOptions: [],
      selectGroupOptions1: [],
      selectGroupOptions2: [],
      selectGroupOptions3: [],
      selectAddressOptions1: [],
      selectAddressOptions2: [],
      selectAddressOptions3: [],
      addressOptions1: [],
      addressOptions2: [],
      selectOptions: []
      //   form: this.$form.createForm(this, { name: 'dynamic_search' })
    }
  },
  created() {
    this.init()
  },
  methods: {
    init() {
      // 保存初始值的
      // eslint-disable-next-line no-undef
      this.initSearchParams = _.cloneDeep(this.searchParams)
      this.initSearchParams.merchantNo = '' // 财务管理 商户账户流水使用
      this.setCascderOptions(this.items)
      this.setSelectGroupOption(this.items)
      this.setSelectAddressOption(this.items)
      this.setAddressOption(this.items)
      this.setSelectOptions(this.items)
    },
    handleSearch() {
      console.log(this.searchParams, 'searchParams')

      // eslint-disable-next-line no-undef
      const cpValue = _.cloneDeep(this.searchParams)
      this.$emit('update:searchParams', cpValue)
      this.$emit('change', cpValue)
      this.$emit('search', cpValue)
    },
    handleReset() {
      // eslint-disable-next-line no-undef
      this.addressOptions2 = [] // 省市的清除
      const cpValue = _.cloneDeep(this.initSearchParams)
      this.$emit('update:searchParams', cpValue)
      this.$emit('change', cpValue)
      this.$emit('reset', cpValue)
    },
    SetOpt(data, value) {
      if (data && data.length > 0) {
        data.forEach(item => {
          item.label = item.name
          item.value = item[value]
          if (item.children && item.children.length > 0) {
            this.SetOpt(item.children, value)
          } else {
            item.children = null
          }
        })
      }
      return data
    },
    async setSelectOptions(data) {
      const arr = data.filter(item => item.type === 'select')
      let reqFunc = null
      let value = null
      if (arr && arr.length > 0) {
        reqFunc = arr[0].reqFunc
        value = arr[0].value
        if (!reqFunc) return
        const res = await reqFunc()
        this.selectOptions = res.data
      }
    },
    async setCascderOptions(data) {
      const arr = data.filter(item => item.type === 'cascaderThree')
      let reqFunc = null
      let value = null
      if (arr && arr.length > 0) {
        reqFunc = arr[0].reqFunc
        value = arr[0].value
        const res = await reqFunc()
        this.cascaderThreeOptions = this.SetOpt(res, value)
        console.log(this.cascaderThreeOptions, 'this.cascaderThreeOptionsthis.cascaderThreeOptions')
      }
    },
    async setSelectGroupOption(data) {
      const arr = data.filter(item => item.type === 'selectGroup3')
      let reqFunc = null
      let value = null
      if (arr && arr.length > 0) {
        reqFunc = arr[0].reqFunc
        value = arr[0].value
        const res = await reqFunc()
        if (arr[0].mark && arr[0].mark === 'category') {
          this.selectGroupOptions1 = this._filterCategoryData(res.data, 0)
        } else {
          this.selectGroupOptions1 = this.SetOpt(res, value)
        }
      }
    },
    async setSelectAddressOption(data) {
      const arr = data.filter(item => item.type === 'selectAddress')
      const reqFunc = null
      if (arr && arr.length > 0) {
        const { IsAmapCode } = arr[0]
        if (IsAmapCode) {
          const res = await getByAmapCode({ code: 0 })
          this.selectAddressOptions1 = res
        } else {
          const res = await getProvince({ code: 0 })
          this.selectAddressOptions1 = res.list
        }
      }
    },
    async setAddressOption(data) {
      const arr = data.filter(item => item.type === 'selectAddress2')
      if (arr.length) {
        const { key1, key2 } = arr[0]
        this.searchParams[key1] = []
        this.searchParams[key2] = []
        const reqFunc = null
        if (arr && arr.length > 0) {
          const res = await getRolesAddress({ addressId: '0' })
          const list = res.filter(item => item.manage == true)
          this.addressOptions1 = list
        }
      }
    },
    async searchCascderOptions(item) {
      const { key, searchKey, func } = item
      const params = {
        [searchKey]: this.searchParams[key],
        pageNum: 1,
        pageSize: 20
      }
      const { list } = await func(params)
      this.cascderOptions1 = filterCascaderData(list)
    },
    selectGroupChange1(data) {
      const arr = this.items.filter(item => item.type === 'selectGroup3')
      const { value, key2, key3 } = arr[0]
      this.searchParams[key2] = ''
      this.searchParams[key3] = ''
      this.selectGroupOptions1.forEach(item => {
        if (data === item[value]) {
          this.selectGroupOptions2 = item.children
        }
      })
    },
    selectGroupChange2(data) {
      const arr = this.items.filter(item => item.type === 'selectGroup3')
      const { value, key3 } = arr[0]
      this.searchParams[key3] = ''
      this.selectGroupOptions2.forEach(item => {
        if (data === item[value]) {
          this.selectGroupOptions3 = item.children
        }
      })
    },
    async selectAddressChange1(data) {
      console.log(data)
      const arr = this.items.filter(item => item.type === 'selectAddress')
      const { key2, key3, props1, IsAmapCode } = arr[0]
      if (!key2) return
      this.searchParams[key2] = ''
      this.searchParams[key3] = ''
      const findItem = this.selectAddressOptions1.find(item => item[props1.value] === data)
      if (IsAmapCode) {
        const res = await getByAmapCode({ code: findItem[props1.value] })
        this.selectAddressOptions2 = res
      } else {
        const res = await getCity({ cityPcode: findItem[props1.value] })
        this.selectAddressOptions2 = res.list
      }
    },
    async selectAddressChange2(data) {
      const arr = this.items.filter(item => item.type === 'selectAddress')
      const { key3, props2, IsAmapCode } = arr[0]
      if (!key3) return
      this.searchParams[key3] = ''
      const findItem = this.selectAddressOptions2.find(item => item[props2.value] === data)
      if (IsAmapCode) {
        const res = await getByAmapCode({ code: findItem[props2.value] })
        this.selectAddressOptions3 = res
      } else {
        const res = await getDistrict({ couPcode: findItem[props2.value] })
        this.selectAddressOptions3 = res.list
      }
    },
    selectAddressChange3() {
      console.log(this.searchParams)
      console.log(this.selectAddressOptions3)
    },
    async addressChange1(data) {
      console.log(data)
      const arr = this.items.filter(item => item.type === 'selectAddress2')
      const { key1, key2 } = arr[0]
      this.searchParams[key2] = []
      const res = await getRolesAddress({ addressId: data })
      const list = res.filter(item => item.manage == true)
      this.addressOptions2 = list
    },
    addressChange2(data) {
      console.log(data)
      // console.log(this.addressOptions2)
    },
    // 联想搜索
    async remoteMethod(query, params) {
      console.log(query, 'query')
      console.log(params, 'params')
      const { model } = params
      const res = await this.requestApi(params, query)
      if (model === '2') {
        const remoteOptions = []
        const { list } = res
        if (list && list.length > 0) {
          list.forEach(item => {
            remoteOptions.push({
              userId: item,
              ownerName: item
            })
          })
        }
        this.remoteOptions = remoteOptions
      } else if (model === '3') {
        const { list } = res
        this.remoteOptions = list
      } else {
        this.remoteOptions = res
      }
      console.log(this.remoteOptions)
    },
    // 请求接口封装成动态接收api地址
    async requestApi(params, query) {
      const { url, searchKey, resultKey, contentType } = params
      const reqOpt = url.split('|')
      const [method, _url] = reqOpt[1] ? reqOpt : ['post', reqOpt[0]]
      const reqKey = method.toLowerCase() === 'post' ? 'data' : 'params'
      const requestParams = {}
      requestParams[searchKey] = query
      const res = await request({
        url: _url,
        method,
        [reqKey]: requestParams,
        headers: {
          'Content-Type': contentType
        }
      })
      const { data } = res
      if (data) {
        return data[resultKey]
      } else {
        return res
      }
    },
    // 绑定属性 继承element相关组件的全部属性
    setAttrs(params) {
      // eslint-disable-next-line
      const { slot, ...options } = params
      return { ...options }
    },
    // 处理经营品类数据
    _filterCategoryData(list, parentId) {
      const cloneData = JSON.parse(JSON.stringify(list))
      const tree = cloneData.filter((father) => {
        const branchArr = cloneData.filter((child) => {
          return father.id == child.parentId
        })
        if (branchArr.length > 0) {
          father.children = branchArr
        }
        return father.parentId === parentId
      })
      return tree
    }
  }
}
</script>
<style lang="scss" scoped>
.search-form {
  .el-form {
    overflow: hidden;
  }
  /deep/ .el-form-item {
    margin-bottom: 20px;
    margin-right: 10px;
    display: flex;
    .el-form-item__label {
      padding: 0 !important;
      margin-right: 10px;
    }
    .el-form-item__content {
      flex: 1;
    }
  }
  /deep/ .el-input__inner {
    height: 32px !important;
  }
  /deep/ .el-input,
  .el-cascader,
  .el-select,
  .el-date-editor {
    width: 100%;
  }
  /deep/.section-input {
    width: calc((100% - 20px) / 2);
  }
  .symbol {
    display: inline-block;
    text-align: center;
    width: 20px;
  }
  .button-group {
    display: inline-block;
    vertical-align: top;
  }
  .extra-button-container {
    .extra-button-right {
      .extra-button-container {
        .extra-button-right {
          float: right;
        }
      }
    }
  }
}
</style>
